# -*- coding: utf-8 -*-
import logging
from datetime import datetime
from common.black_account.model import (WithdrawBlack, WITHDRAW_BLACK_STATUS, WITHDRAW_BLACK_TYPE,
                                        BlackModification, WITHDRAW_BLACK_GROUP, WITHDRAW_BLACK_ACCOUNT_MAP)
from common.utils.db import list_object
from common.utils.decorator import sql_wrapper
from common.utils.tz import utc_to_local_str
from common import orm

_LOGGER = logging.getLogger(__name__)


@sql_wrapper
def list_withdraw_black(query_dct):
    return list_object(query_dct, WithdrawBlack)


@sql_wrapper
def list_type_account(type, status=WITHDRAW_BLACK_STATUS.ENABLE):
    items = WithdrawBlack.query.filter(
        WithdrawBlack.type == type, WithdrawBlack.status == status).filter().all()
    type_accounts = []
    for item in items:
        data = item.as_dict()
        type_accounts.append(data['type_account'])
    return type_accounts


def get_withdraw_black_list(target_type=None):
    ret = {}
    query = orm.session.query(WithdrawBlack.type_account).filter(WithdrawBlack.status == WITHDRAW_BLACK_STATUS.ENABLE)
    for key in WITHDRAW_BLACK_TYPE.to_dict():
        ret[key] = [unicode(black_account[0]) for black_account in query.filter(WithdrawBlack.type == key).all()]
    if target_type:
        return ret.get(target_type, [])
    return ret


def create_withdraw_black(type_account, type, user_id, money=0,
                          status=WITHDRAW_BLACK_STATUS.ENABLE, note=None, auto_commit=False):
    withdraw_black = WithdrawBlack()
    withdraw_black.user_id = user_id
    withdraw_black.type_account = type_account
    withdraw_black.type = type
    withdraw_black.status = status
    withdraw_black.money = money
    withdraw_black.note = note
    withdraw_black.created_at = withdraw_black.updated_at = datetime.utcnow()
    withdraw_black.save(auto_commit=auto_commit)
    orm.session.flush()
    return withdraw_black.as_dict()


def get_withdraw_black_related_user_id(info):
    from common.account.db.account import get_financial_type_account_by_num, exists_phone
    user_id = 0
    _LOGGER.info(info['type'])
    _LOGGER.info(WITHDRAW_BLACK_GROUP.get('withdraw_black_list', []))
    if info['type'] in WITHDRAW_BLACK_GROUP.get('withdraw_black_list', []):
        user_id = info['type_account']
    elif info['type'] in WITHDRAW_BLACK_GROUP.get('withdraw_black_account_list', []):
        account_type = WITHDRAW_BLACK_ACCOUNT_MAP.get(info['type'])
        financial_account = get_financial_type_account_by_num(info['type_account'], account_type)
        user_id = financial_account.user_id if financial_account else 0
    elif info['type'] in WITHDRAW_BLACK_ACCOUNT_MAP.get('withdraw_black_account_info', []):
        account = exists_phone(info['type_account'])
        user_id = account.id
    return user_id


def create_withdraw_black_modification(user_id, admin_id, mod_type, type_account, status, reason=''):
    withdraw_black_mod = BlackModification()
    withdraw_black_mod.user_id = user_id
    withdraw_black_mod.admin_id = admin_id
    withdraw_black_mod.mod_type = mod_type
    withdraw_black_mod.type_account = type_account
    withdraw_black_mod.status = status
    withdraw_black_mod.reason = reason
    withdraw_black_mod.save(auto_commit=False)
    orm.session.flush()
    return withdraw_black_mod.as_dict()


def update_withdraw_black(info, admin_id, status=WITHDRAW_BLACK_STATUS.ENABLE):
    withdraw_black = WithdrawBlack.query.with_for_update().filter(
        WithdrawBlack.type_account == info['type_account']).filter(WithdrawBlack.type == info['type']).first()
    user_id = get_withdraw_black_related_user_id(info)
    if withdraw_black:
        withdraw_black.status = status
        withdraw_black.updated_at = datetime.utcnow()
        withdraw_black.user_id = user_id
        if 'money' in info.keys():
            withdraw_black.money = info['money']
        if 'note' in info.keys() and info['note'] is not None:
            withdraw_black.note = info['note']
        withdraw_black.save(auto_commit=False)
        orm.session.flush()
        withdraw_black_dct = withdraw_black.as_dict()
    else:
        withdraw_black_dct = create_withdraw_black(info['type_account'], info['type'], user_id, info['money'],
                                                   status, info['note'])
    create_withdraw_black_modification(user_id, admin_id, withdraw_black_dct['type'],
                                       withdraw_black_dct['type_account'], withdraw_black_dct['status'], info['reason'])
    orm.session.commit()
    return withdraw_black


@sql_wrapper
def get_withdraw_black_modification_list(query_dct, disable_paginate):
    if disable_paginate:
        query, total_count = list_object(query_dct, BlackModification, disable_paginate)
        return query.all(), total_count
    return list_object(query_dct, BlackModification, disable_paginate)


@sql_wrapper
def get_user_black_modification_dict(user_id):
    user_black_modification = BlackModification.query.filter(BlackModification.user_id == user_id)
    ret = {}
    black_type = WITHDRAW_BLACK_TYPE.to_dict()
    black_type.update({'account_banned': '黑名单用户'})
    for key in black_type:
        user_black_type_modification = user_black_modification.filter(BlackModification.mod_type == key).all()
        type_val = []
        for mod in user_black_type_modification:
            mod = mod.as_dict()
            mod['created_at'] = utc_to_local_str(mod['created_at'])
            type_val.append(mod)
        ret.update({key: type_val})
    return ret


@sql_wrapper
def get_black_info_list(query_dct):
    account_type = query_dct.get('account_type')
    account_info = query_dct.get('account_info')
    status = query_dct.get('status')
    page = query_dct.get('$page', 1)
    size = query_dct.get('$size', 15)
    black_type_tuple = (WITHDRAW_BLACK_TYPE.BAD_BANK, WITHDRAW_BLACK_TYPE.BAD_PHONE,
                        WITHDRAW_BLACK_TYPE.BLACK_EQUIPMENT, WITHDRAW_BLACK_TYPE.BLACK_IP,
                        WITHDRAW_BLACK_TYPE.BLACK_PHONE, WITHDRAW_BLACK_TYPE.BLACK_PHONE,
                        WITHDRAW_BLACK_TYPE.BLACK_ALIPAYNO)
    items = WithdrawBlack.query.filter(WithdrawBlack.type.in_(black_type_tuple)).order_by(WithdrawBlack.updated_at.desc())
    if account_type:
        items = items.filter(WithdrawBlack.type == account_type)
    if account_info:
        items = items.filter(WithdrawBlack.type_account == str(account_info))
    if status:
        items = items.filter(WithdrawBlack.status == status)
    total_count = items.count()
    items = items.limit(size).offset(size * (page - 1))
    datas = []
    for item in items:
        item = item.as_dict()
        item['created_at'] = utc_to_local_str(item['created_at'])
        item['updated_at'] = utc_to_local_str(item['updated_at'])
        datas.append(item)

    return total_count, datas